#define WEIGHT_PERIOD (MILLISECS(100))
#define WEIGHT_SAFETY (MILLISECS(5))
-
-struct sedf_dom_info
+struct sedf_dom_info {
+ struct domain *domain;
+};
+struct sedf_edom_info
{
- struct domain *owner;
+ struct exec_domain *exec_domain;
struct list_head list;
struct list_head extralist[2];
short weight;
/*Bookkeeping*/
- s_time_t absdead;
- s_time_t sched_start;
+ s_time_t deadl_abs;
+ s_time_t sched_start_abs;
s_time_t cputime;
- s_time_t absblock;
-
- /*time the domain unblocked, used to determine unblocking intervals*/
- s_time_t absunblock;
+ /* times the domain un-/blocked */
+ s_time_t block_abs;
+ s_time_t unblock_abs;
/*scores for {util, block penalty}-weighted extratime distribution*/
int score[2];
struct list_head extraq[2];
};
-#define DOM_INFO(d) ((struct sedf_dom_info *)((d)->sched_priv))
+#define EDOM_INFO(d) ((struct sedf_edom_info *)((d)->ed_sched_priv))
#define CPU_INFO(cpu) ((struct sedf_cpu_info *)schedule_data[cpu].sched_priv)
-#define LIST(d) (&DOM_INFO(d)->list)
-#define EXTRALIST(d,i) (&(DOM_INFO(d)->extralist[i]))
+#define LIST(d) (&EDOM_INFO(d)->list)
+#define EXTRALIST(d,i) (&(EDOM_INFO(d)->extralist[i]))
#define RUNQ(cpu) (&CPU_INFO(cpu)->runnableq)
#define WAITQ(cpu) (&CPU_INFO(cpu)->waitq)
#define EXTRAQ(cpu,i) (&(CPU_INFO(cpu)->extraq[i]))
-#define IDLETASK(cpu) ((struct domain *)schedule_data[cpu].idle)
+#define IDLETASK(cpu) ((struct exec_domain *)schedule_data[cpu].idle)
-#define PERIOD_BEGIN(inf) ((inf)->absdead - (inf)->period)
+#define PERIOD_BEGIN(inf) ((inf)->deadl_abs - (inf)->period)
#define MIN(x,y) (((x)<(y))?(x):(y))
#define DIV_UP(x,y) (((x) + (y) - 1) / y)
-static xmem_cache_t *dom_info_cache;
-
static void sedf_dump_cpu_state(int i);
-static inline int extraq_on(struct domain *d, int i) {
+static inline int extraq_on(struct exec_domain *d, int i) {
return ((EXTRALIST(d,i)->next != NULL) &&
(EXTRALIST(d,i)->next != EXTRALIST(d,i)));
}
-static inline void extraq_add_head(struct domain *d, int i)
+static inline void extraq_add_head(struct exec_domain *d, int i)
{
list_add(EXTRALIST(d,i), EXTRAQ(d->processor,i));
}
-static inline void extraq_add_tail(struct domain *d, int i)
+static inline void extraq_add_tail(struct exec_domain *d, int i)
{
list_add_tail(EXTRALIST(d,i), EXTRAQ(d->processor,i));
}
-static inline void extraq_del(struct domain *d, int i)
+static inline void extraq_del(struct exec_domain *d, int i)
{
struct list_head *list = EXTRALIST(d,i);
/*if (!extraq_on(d,i)) {
- PRINT(0,"extraq_del: domain %i is NOT on L%i extraq "\
- "HALTING\n",d->id,i);
+ PRINT(0,"extraq_del: domain %i.%i is NOT on L%i extraq "\
+ "HALTING\n",d->domain->id, d->eid,i);
sedf_dump_cpu_state(0);(*((int*)0))++;
}*/
- PRINT(3, "Removing domain %i from L%i extraq\n", d->id,i);
+ PRINT(3, "Removing domain %i.%i from L%i extraq\n", d->domain->id,
+ d->eid, i);
list_del(list);
list->next = NULL;
}
each entry, in order to avoid overflow. The algorithm works by simply
charging each domain that recieved extratime with an inverse of its weight.
*/
-static inline void extraq_add_sort_update(struct domain *d, int i, int sub) {
- struct list_head *cur;
- struct sedf_dom_info *curinf;
+static inline void extraq_add_sort_update(struct exec_domain *d, int i, int sub) {
+ struct list_head *cur;
+ struct sedf_edom_info *curinf;
/*if (extraq_on(d,i)) {
- PRINT(0,"extraq_add_sort_update: domain %i is already on "\
- "L%i extraq! HALTING\n",d->id,i);
+ PRINT(0,"extraq_add_sort_update: domain %i.%i is already on "\
+ "L%i extraq! HALTING\n",d->domain->id, d->eid, i);
sedf_dump_cpu_state(0);(*((int*)0))++;
}*/
- PRINT(3, "Adding domain %i (score= %i, short_pen= %lli) to L%i "\
- "extraq\n", d->id, DOM_INFO(d)->score[i],
- DOM_INFO(d)->short_block_lost_tot, i);
+ PRINT(3, "Adding domain %i.%i (score= %i, short_pen= %lli) to L%i "\
+ "extraq\n", d->domain->id, d->eid, EDOM_INFO(d)->score[i],
+ EDOM_INFO(d)->short_block_lost_tot, i);
/*iterate through all elements to find our "hole" and on our way
update all the other scores*/
list_for_each(cur,EXTRAQ(d->processor,i)){
- curinf = list_entry(cur,struct sedf_dom_info,extralist[i]);
+ curinf = list_entry(cur,struct sedf_edom_info,extralist[i]);
curinf->score[i] -= sub;
- if (DOM_INFO(d)->score[i] < curinf->score[i])
+ if (EDOM_INFO(d)->score[i] < curinf->score[i])
break;
else
- PRINT(4,"\tbehind domain %i (score= %i)\n",
- curinf->owner->id, curinf->score[i]);
+ PRINT(4,"\tbehind domain %i.%i (score= %i)\n",
+ curinf->exec_domain->domain->id,
+ curinf->exec_domain->eid, curinf->score[i]);
}
/*cur now contains the element, before which we'll enqueue*/
PRINT(3, "\tlist_add to %x\n", cur->prev);
if ((cur != EXTRAQ(d->processor,i)) && sub)
for (cur = cur->next; cur != EXTRAQ(d->processor,i);
cur = cur-> next) {
- curinf = list_entry(cur,struct sedf_dom_info,
+ curinf = list_entry(cur,struct sedf_edom_info,
extralist[i]);
curinf->score[i] -= sub;
- PRINT(4, "\tupdating domain %i (score= %llu)\n",
- curinf->owner->id, curinf->score[i]);
+ PRINT(4, "\tupdating domain %i.%i (score= %llu)\n",
+ curinf->exec_domain->domain->id,
+ curinf->exec_domain->eid, curinf->score[i]);
}
}
-static inline void extraq_check(struct domain *d) {
+static inline void extraq_check(struct exec_domain *d) {
if (extraq_on(d, EXTRA_UTIL_Q)) {
- PRINT(2,"Dom %i is on extraQ\n",d->id);
- if (!(DOM_INFO(d)->extra & EXTRA_AWARE) &&
- !extra_runs(DOM_INFO(d))) {
+ PRINT(2,"Dom %i is on extraQ\n",d->domain->id, d->eid);
+ if (!(EDOM_INFO(d)->extra & EXTRA_AWARE) &&
+ !extra_runs(EDOM_INFO(d))) {
extraq_del(d, EXTRA_UTIL_Q);
- PRINT(2,"Removed dom %i from L1 extraQ\n",d->id);
+ PRINT(2,"Removed dom %i.%i from L1 extraQ\n",
+ d->domain->id, d->eid);
}
} else {
- PRINT(2,"Dom %i is NOT on L1 extraQ\n",d->id);
- if ((DOM_INFO(d)->extra & EXTRA_AWARE) && domain_runnable(d))
+ PRINT(2,"Dom %i.%i is NOT on L1 extraQ\n",d->domain->id,
+ d->eid);
+ if ((EDOM_INFO(d)->extra & EXTRA_AWARE) && domain_runnable(d))
{
#if (EXTRA == EXTRA_ROUNDR)
/*Favour domains which got short unblocked*/
#elif
;
#endif
- PRINT(2,"Added dom %i to L1 extraQ\n",d->id);
+ PRINT(2,"Added dom %i.%i to L1 extraQ\n",d->domain->id,
+ d->eid);
}
}
}
-static inline void __del_from_queue(struct domain *d)
+static inline void __del_from_queue(struct exec_domain *d)
{
struct list_head *list = LIST(d);
- PRINT(3,"Removing domain %i (bop= %llu) from runq/waitq\n", d->id,
- PERIOD_BEGIN(DOM_INFO(d)));
+ PRINT(3,"Removing domain %i.%i (bop= %llu) from runq/waitq\n", d->domain->id,
+ d->eid, PERIOD_BEGIN(EDOM_INFO(d)));
list_del(list);
list->next = NULL;
}
next period; this list is therefore sortet by this time, which is simply
absol. deadline - period
*/
-static inline void __add_to_waitqueue_sort(struct domain *d) {
+static inline void __add_to_waitqueue_sort(struct exec_domain *d) {
struct list_head *cur;
- struct sedf_dom_info *curinf;
+ struct sedf_edom_info *curinf;
- PRINT(3,"Adding domain %i (bop= %llu) to waitq\n", d->id,
- PERIOD_BEGIN(DOM_INFO(d)));
+ PRINT(3,"Adding domain %i.%i (bop= %llu) to waitq\n", d->domain->id,
+ d->eid, PERIOD_BEGIN(EDOM_INFO(d)));
/*iterate through all elements to find our "hole"*/
- list_for_each(cur,WAITQ(d->processor)){
- curinf = list_entry(cur,struct sedf_dom_info,list);
- if (PERIOD_BEGIN(DOM_INFO(d)) < PERIOD_BEGIN(curinf))
+ list_for_each(cur, WAITQ(d->processor)){
+ curinf = list_entry(cur,struct sedf_edom_info,list);
+ if (PERIOD_BEGIN(EDOM_INFO(d)) < PERIOD_BEGIN(curinf))
break;
else
- PRINT(4,"\tbehind domain %i (bop= %llu)\n",
- curinf->owner->id, PERIOD_BEGIN(curinf));
+ PRINT(4,"\tbehind domain %i.%i (bop= %llu)\n",
+ curinf->exec_domain->domain->id,
+ curinf->exec_domain->eid, PERIOD_BEGIN(curinf));
}
/*cur now contains the element, before which we'll enqueue*/
PRINT(3,"\tlist_add to %x\n",cur->prev);
list_add(LIST(d),cur->prev);
-
}
/* adds a domain to the queue of processes which have started their current
on this list is running on the processor, if the list is empty the idle
task will run. As we are implementing EDF, this list is sorted by deadlines.
*/
-static inline void __add_to_runqueue_sort(struct domain *d) {
+static inline void __add_to_runqueue_sort(struct exec_domain *d) {
struct list_head *cur;
- struct sedf_dom_info *curinf;
+ struct sedf_edom_info *curinf;
- PRINT(3,"Adding domain %i (deadl= %llu) to runq\n", d->id,
- DOM_INFO(d)->absdead);
+ PRINT(3,"Adding domain %i.%i (deadl= %llu) to runq\n", d->domain->id,
+ d->eid, EDOM_INFO(d)->deadl_abs);
/*iterate through all elements to find our "hole"*/
list_for_each(cur, RUNQ(d->processor)) {
- curinf = list_entry(cur, struct sedf_dom_info, list);
- if (DOM_INFO(d)->absdead < curinf->absdead)
+ curinf = list_entry(cur, struct sedf_edom_info, list);
+ if (EDOM_INFO(d)->deadl_abs < curinf->deadl_abs)
break;
else
- PRINT(4,"\tbehind domain %i (deadl= %llu)\n",
- curinf->owner->id, curinf->absdead);
+ PRINT(4,"\tbehind domain %i.%i (deadl= %llu)\n",
+ curinf->exec_domain->domain->id,
+ curinf->exec_domain->eid, curinf->deadl_abs);
}
/*cur now contains the element, before which we'll enqueue*/
PRINT(3,"\tlist_add to %x\n",cur->prev);
list_add(LIST(d),cur->prev);
-
}
-static inline int __task_on_queue(struct domain *d) {
+static inline int __task_on_queue(struct exec_domain *d) {
return (((LIST(d))->next != NULL) && (LIST(d)->next != LIST(d)));
}
-/* Initialises the queues and creates the domain info cache */
+/* Initialises the queues */
static int sedf_init_scheduler() {
int i;
PRINT(2,"sedf_init_scheduler was called\n");
for ( i = 0; i < NR_CPUS; i++ ) {
schedule_data[i].sched_priv =
- xmalloc(sizeof(struct sedf_cpu_info));
+ xmalloc(struct sedf_cpu_info);
if ( schedule_data[i].sched_priv == NULL )
return -1;
INIT_LIST_HEAD(WAITQ(i));
INIT_LIST_HEAD(EXTRAQ(i,EXTRA_PEN_Q));
INIT_LIST_HEAD(EXTRAQ(i,EXTRA_UTIL_Q));
}
- dom_info_cache = xmem_cache_create("SEDF dom info",
+//TODO: Remove this stuff if things work!
+ /*dom_info_cache = xmem_cache_create("SEDF dom info",
sizeof(struct sedf_dom_info), 0, 0, 0, NULL);
if ( dom_info_cache == NULL )
{
printk("Could not allocate SLAB cache.\n");
return -1;
- }
+ }*/
return 0;
}
/* Allocates memory for per domain private scheduling data*/
-static int sedf_alloc_task(struct domain *d) {
- PRINT(2,"sedf_alloc_task was called, domain-id %i\n",d->id);
- if ( (d->sched_priv = xmem_cache_alloc(dom_info_cache)) == NULL )
+static int sedf_alloc_task(struct exec_domain *d) {
+ PRINT(2,"sedf_alloc_task was called, domain-id %i.%i\n",d->domain->id,
+ d->eid);
+ if (d->domain->sched_priv == NULL) {
+ if ((d->domain->sched_priv =
+ xmalloc(struct sedf_dom_info)) == NULL )
return -1;
- memset(d->sched_priv, 0, sizeof(struct sedf_dom_info));
+ memset(d->domain->sched_priv, 0, sizeof(struct sedf_dom_info));
+ }
+ if ((d->ed_sched_priv = xmalloc(struct sedf_edom_info)) == NULL )
+ return -1;
+ memset(d->ed_sched_priv, 0, sizeof(struct sedf_edom_info));
return 0;
}
/* Setup the sedf_dom_info */
-static void sedf_add_task(struct domain *d)
+static void sedf_add_task(struct exec_domain *d)
{
- struct sedf_dom_info *inf=DOM_INFO(d);
- inf->owner = d;
+ struct sedf_edom_info *inf=EDOM_INFO(d);
+ inf->exec_domain = d;
- PRINT(2,"sedf_add_task was called, domain-id %i\n",d->id);
- if (d->id==0) {
+ PRINT(2,"sedf_add_task was called, domain-id %i.%i\n",d->domain->id,
+ d->eid);
+
+ if (d->domain->id==0) {
/*set dom0 to something useful to boot the machine*/
inf->period = MILLISECS(20);
inf->slice = MILLISECS(15);
inf->latency = 0;
- inf->absdead = 0;
+ inf->deadl_abs = 0;
inf->extra = EXTRA_NONE;/*EXTRA_AWARE; */
}
else {
/*other domains run in best effort mode*/
inf->period = MILLISECS(20);
inf->slice = 0;
- inf->absdead = 0;
+ inf->deadl_abs = 0;
inf->latency = 0;
inf->extra = EXTRA_AWARE;
}
/* Frees memory used by domain info */
static void sedf_free_task(struct domain *d)
{
+ int i;
PRINT(2,"sedf_free_task was called, domain-id %i\n",d->id);
ASSERT(d->sched_priv != NULL);
- xmem_cache_free(dom_info_cache, d->sched_priv);
+ xfree(d->sched_priv);
+
+ for (i = 0; i < MAX_VIRT_CPUS; i++)
+ if ( d->exec_domain[i] ) {
+ ASSERT(d->exec_domain[i]->ed_sched_priv != NULL);
+ xfree(d->exec_domain[i]->ed_sched_priv);
+ }
}
/* Initialises idle task */
-static int sedf_init_idle_task(struct domain *d) {
- PRINT(2,"sedf_init_idle_task was called, domain-id %i\n",d->id);
+static int sedf_init_idle_task(struct exec_domain *d) {
+ PRINT(2,"sedf_init_idle_task was called, domain-id %i.%i\n",
+ d->domain->id, d->eid);
if ( sedf_alloc_task(d) < 0 )
return -1;
sedf_add_task(d);
- DOM_INFO(d)->absdead = 0;
- set_bit(DF_RUNNING, &d->flags);
+ EDOM_INFO(d)->deadl_abs = 0;
+ set_bit(EDF_RUNNING, &d->ed_flags);
/*the idle task doesn't have to turn up on any list...*/
return 0;
}
/* handles the rescheduling, bookkeeping of domains running in their realtime-time :)*/
-static inline void desched_edf_dom (s_time_t now, struct domain* d) {
- struct sedf_dom_info* inf = DOM_INFO(d);
+static inline void desched_edf_dom (s_time_t now, struct exec_domain* d) {
+ struct sedf_edom_info* inf = EDOM_INFO(d);
/*current domain is running in real time mode*/
/*update the domains cputime*/
- inf->cputime += now - inf->sched_start;
+ inf->cputime += now - inf->sched_start_abs;
/*scheduling decisions, which don't remove the running domain
from the runq*/
return;
__del_from_queue(d);
- /*if (__task_on_queue(current)) {
- PRINT(0,"domain %i was removed but still on run/waitq => "\
- "HALT\n",current->id);
+ /*if (__task_on_queue(d)) {
+ PRINT(0,"domain %i.%i was removed but still on run/waitq => "\
+ "HALT\n",d->domain->id, d->eid);
sedf_dump_cpu_state(0);(*((int*)0))++;
}*/
if (inf->period < inf->period_orig) {
/*this domain runs in latency scaling or burst mode*/
#if (UNBLOCK == UNBLOCK_BURST)
- if (now - inf->absunblock >= 2 * inf->period)
+ if (now - inf->unblock_abs >= 2 * inf->period)
#endif
{
inf->period *= 2; inf->slice *= 2;
}
}
/*set next deadline*/
- inf->absdead += inf->period;
+ inf->deadl_abs += inf->period;
}
- /*if (inf->absdead<now)
- printk("Domain %i exceeded it't deadline!!!! "\
- "(now: %llu ddl: %llu)\n", current->id, now,
- inf->absdead);*/
+ /*if (inf->deadl_abs < now)
+ printk("Domain %i.%i exceeded it't deadline!!!! "\
+ "(now: %llu ddl: %llu)\n", d->domain->id, d->eid, now,
+ inf->deadl_abs);*/
/*add a runnable domain to the waitqueue*/
if (domain_runnable(d))
__add_to_waitqueue_sort(d);
else {
- /*we have a blocked realtime task*/
- inf->absblock = now;
+ /*we have a blocked realtime task -> remove it from exqs too*/
+ inf->block_abs = now;
#if (EXTRA > EXTRA_OFF)
#if (EXTRA == EXTRA_BLOCK_WEIGHT)
- if (extraq_on(d,EXTRA_PEN_Q)) extraq_del(d,EXTRA_PEN_Q);
+ if (extraq_on(d, EXTRA_PEN_Q)) extraq_del(d, EXTRA_PEN_Q);
#endif
- if (extraq_on(d,EXTRA_UTIL_Q)) extraq_del(d,EXTRA_UTIL_Q);
+ if (extraq_on(d, EXTRA_UTIL_Q)) extraq_del(d, EXTRA_UTIL_Q);
#endif
}
}
/* Update all elements on the queues */
-static inline void update_queues(
-s_time_t now, struct list_head* runq, struct list_head* waitq) {
+static inline void update_queues(s_time_t now, struct list_head* runq,
+struct list_head* waitq) {
struct list_head *cur,*tmp;
- struct sedf_dom_info *curinf;
+ struct sedf_edom_info *curinf;
PRINT(3,"Updating waitq..\n");
/*check for the first elements of the waitqueue, whether their
next period has already started*/
list_for_each_safe(cur, tmp, waitq) {
- curinf = list_entry(cur, struct sedf_dom_info, list);
- PRINT(4,"\tLooking @ dom %i\n", curinf->owner->id);
+ curinf = list_entry(cur, struct sedf_edom_info, list);
+ PRINT(4,"\tLooking @ dom %i.%i\n",
+ curinf->exec_domain->domain->id, curinf->exec_domain->eid);
if (PERIOD_BEGIN(curinf) <= now) {
- __del_from_queue(curinf->owner);
- __add_to_runqueue_sort(curinf->owner);
+ __del_from_queue(curinf->exec_domain);
+ __add_to_runqueue_sort(curinf->exec_domain);
}
else
break;
/*process the runq, find domains that are on
the runqueue which shouldn't be there*/
list_for_each_safe(cur, tmp, runq) {
- curinf = list_entry(cur,struct sedf_dom_info,list);
- PRINT(4,"\tLooking @ dom %i\n", curinf->owner->id);
+ curinf = list_entry(cur,struct sedf_edom_info,list);
+ PRINT(4,"\tLooking @ dom %i.%i\n",
+ curinf->exec_domain->domain->id, curinf->exec_domain->eid);
if (unlikely(curinf->slice == 0)) {
/*ignore domains with empty slice*/
- PRINT(4,"\tUpdating zero-slice domain %i\n",
- curinf->owner->id);
- __del_from_queue(curinf->owner);
+ PRINT(4,"\tUpdating zero-slice domain %i.%i\n",
+ curinf->exec_domain->domain->id,
+ curinf->exec_domain->eid);
+ __del_from_queue(curinf->exec_domain);
/*move them to their next period*/
- curinf->absdead += curinf->period;
+ curinf->deadl_abs += curinf->period;
/*and put them back into the queue*/
- __add_to_waitqueue_sort(curinf->owner);
+ __add_to_waitqueue_sort(curinf->exec_domain);
}
else {
- if (unlikely((curinf->absdead < now) ||
+ if (unlikely((curinf->deadl_abs < now) ||
(curinf->cputime > curinf->slice))) {
/*we missed the deadline or the slice was
already finished... might hapen because
of dom_adj.*/
- PRINT(4,"\tDomain %i exceeded it's deadline/"\
+ PRINT(4,"\tDomain %i.%i exceeded it's deadline/"\
"slice (%llu / %llu) now: %llu "\
- "cputime: %llu\n", curinf->owner->id,
- curinf->absdead, curinf->slice, now,
+ "cputime: %llu\n",
+ curinf->exec_domain->domain->id,
+ curinf->exec_domain->eid,
+ curinf->deadl_abs, curinf->slice, now,
curinf->cputime);
- __del_from_queue(curinf->owner);
+ __del_from_queue(curinf->exec_domain);
/*common case: we miss one period!*/
- curinf->absdead += curinf->period;
+ curinf->deadl_abs += curinf->period;
/*if we are still behind: modulo arithmetic,
force deadline to be in future and
aligned to period borders!*/
- if (unlikely(curinf->absdead < now))
- curinf->absdead +=
- DIV_UP(now - curinf->absdead,
+ if (unlikely(curinf->deadl_abs < now))
+ curinf->deadl_abs +=
+ DIV_UP(now - curinf->deadl_abs,
curinf->period) * curinf->period;
-
+ ASSERT(curinf->deadl_abs > now);
/*give a fresh slice*/
curinf->cputime = 0;
- if (PERIOD_BEGIN(curinf) < now)
- __add_to_waitqueue_sort(curinf->owner);
+ if (PERIOD_BEGIN(curinf) > now)
+ __add_to_waitqueue_sort(curinf->exec_domain);
else
- __add_to_runqueue_sort(curinf->owner);
+ __add_to_runqueue_sort(curinf->exec_domain);
}
else
break;
weighted ext.: insert in sorted list by score
if the domain is blocked / has regained its short-block-loss
time it is not put on any queue */
-static inline void desched_extra_dom(s_time_t now, struct domain* d) {
- struct sedf_dom_info *inf = DOM_INFO(d);
+static inline void desched_extra_dom(s_time_t now, struct exec_domain* d) {
+ struct sedf_edom_info *inf = EDOM_INFO(d);
int i = extra_get_cur_q(inf);
#if (EXTRA == EXTRA_SLICE_WEIGHT || EXTRA == EXTRA_BLOCK_WEIGHT)
/*fresh slice for the next run*/
inf->cputime = 0;
/*accumulate total extratime*/
- inf->extra_time_tot += now - inf->sched_start;
+ inf->extra_time_tot += now - inf->sched_start_abs;
/*remove extradomain from head of the queue*/
extraq_del(d, i);
/*domain was running in L0 extraq*/
/*reduce block lost, probably more sophistication here!*/
/*inf->short_block_lost_tot -= EXTRA_QUANTUM;*/
- inf->short_block_lost_tot -= now - inf->sched_start;
- PRINT(3,"Domain %i: Short_block_lost: %lli\n",
- inf->owner->id, inf->short_block_lost_tot);
+ inf->short_block_lost_tot -= now - inf->sched_start_abs;
+ PRINT(3,"Domain %i.%i: Short_block_loss: %lli\n",
+ inf->exec_domain->domain->id, inf->exec_domain->eid,
+ inf->short_block_lost_tot);
if (inf->short_block_lost_tot <= 0) {
- PRINT(4,"Domain %i compensated short block loss!\n");
+ PRINT(4,"Domain %i.%i compensated short block loss!\n",
+ inf->exec_domain->domain->id, inf->exec_domain->eid);
/*we have (over-)compensated our block penalty*/
inf->short_block_lost_tot = 0;
/*we don't want a place on the penalty queue anymore!*/
{
/*domain was running in L1 extraq => score is inverse of
utilization and is used somewhat incremental!*/
+//TODO: Check for weights => use them for calculating the score!
if (inf->slice)
/*NB: use fixed point arithmetic with 10 bits*/
inf->score[EXTRA_UTIL_Q] = (inf->period << 10) /
/*add according to score: weighted round robin*/
extraq_add_sort_update(d, i, oldscore);
else {
- inf->absblock = now;
+ inf->block_abs = now;
/*if (!__task_on_queue(d))
- printf("Oops... We attempt to remove d %i from the "\
- "waitq, but it is not on :(\n",d->id);*/
+ printf("Oops... We attempt to remove d %i.%i from the "\
+ "waitq, but it is not on :(\n", d->domain->id,
+ d->eid);*/
/*remove this blocked domain from the waitq!*/
__del_from_queue(d);
/*make sure that we remove a blocked domain from the other
extraq aswell (this caused hours of debugging!)*/
#if (EXTRA == EXTRA_BLOCK_WEIGHT)
if (i == EXTRA_PEN_Q) {
- if (extraq_on(d,EXTRA_UTIL_Q))
- extraq_del(d,EXTRA_UTIL_Q);
+ if (extraq_on(d, EXTRA_UTIL_Q))
+ extraq_del(d, EXTRA_UTIL_Q);
}
else {
- if (extraq_on(d,EXTRA_PEN_Q))
- extraq_del(d,EXTRA_PEN_Q);
+ if (extraq_on(d, EXTRA_PEN_Q))
+ extraq_del(d, EXTRA_PEN_Q);
}
#endif
}
#endif
/*if (!domain_runnable(d)) {
- if (extraq_on(d,EXTRA_UTIL_Q)) {
- PRINT(0,"domain %i is blocked but still on L1 "\
- "xq=> HALT\n",d->id);
+ if (extraq_on(d, EXTRA_UTIL_Q)) {
+ PRINT(0,"domain %i.%i is blocked but still on L1 "\
+ "xq=> HALT\n",d->domain->id, d->eid);
sedf_dump_cpu_state(0);(*((int*)0))++;
}
if (__task_on_queue(d)) {
- PRINT(0,"domain %i is blocked but still on run/waitq"\
- "=> HALT\n",d->id);
+ PRINT(0,"domain %i.%i is blocked but still on run/waitq"\
+ "=> HALT\n",d->domain->id, d->eid);
sedf_dump_cpu_state(0);(*((int*)0))++;
}
}*/
}
#endif
-
-static inline task_slice_t sedf_do_extra_schedule
-(s_time_t now, s_time_t end_xt, struct list_head *extraq[], int cpu) {
- task_slice_t ret;
- struct sedf_dom_info *runinf;
+static inline struct task_slice sedf_do_extra_schedule (s_time_t now, s_time_t end_xt, struct list_head *extraq[], int cpu) {
+ struct task_slice ret;
+ struct sedf_edom_info *runinf;
+ /* Enough time left to use for extratime? */
if (end_xt - now < EXTRA_QUANTUM)
goto return_idle;
#if (EXTRA == EXTRA_BLOCK_WEIGHT)
/*we still have elements on the level 0 extraq
=> let those run first!*/
runinf = list_entry(extraq[EXTRA_PEN_Q]->next,
- struct sedf_dom_info, extralist[EXTRA_PEN_Q]);
+ struct sedf_edom_info, extralist[EXTRA_PEN_Q]);
runinf->extra |= EXTRA_RUN_PEN;
- ret.task = runinf->owner;
+ ret.task = runinf->exec_domain;
ret.time = EXTRA_QUANTUM;
#ifdef SEDF_STATS
runinf->pen_extra_slices++;
if (!list_empty(extraq[EXTRA_UTIL_Q])) {
/*use elements from the normal extraqueue*/
runinf = list_entry(extraq[EXTRA_UTIL_Q]->next,
- struct sedf_dom_info,extralist[EXTRA_UTIL_Q]);
+ struct sedf_edom_info, extralist[EXTRA_UTIL_Q]);
runinf->extra |= EXTRA_RUN_UTIL;
- ret.task = runinf->owner;
+ ret.task = runinf->exec_domain;
ret.time = EXTRA_QUANTUM;
}
else
-timeslice for the current period used up
-domain on waitqueue has started it's period
-and various others ;) in general: determine which domain to run next*/
-static task_slice_t sedf_do_schedule(s_time_t now)
+static struct task_slice sedf_do_schedule(s_time_t now)
{
int cpu = current->processor;
struct list_head *runq = RUNQ(cpu);
struct list_head *waitq = WAITQ(cpu);
#if (EXTRA > EXTRA_OFF)
- struct sedf_dom_info *inf = DOM_INFO(current);
- struct list_head *extraq[] = {EXTRAQ(cpu,EXTRA_PEN_Q),
+ struct sedf_edom_info *inf = EDOM_INFO(current);
+ struct list_head *extraq[] = {EXTRAQ(cpu, EXTRA_PEN_Q),
EXTRAQ(cpu, EXTRA_UTIL_Q)};
#endif
- task_slice_t ret;
+ struct task_slice ret;
/*int i = 0;*/
/*idle tasks don't need any of the following stuf*/
- if (is_idle_task(current))
+ if (is_idle_task(current->domain))
goto check_waitq;
#if (EXTRA > EXTRA_OFF)
}
/*if (!domain_runnable(current)) {
if (extraq_on(current,EXTRA_UTIL_Q)) {
- PRINT(0,"domain %i is blocked but still on L1 xq"\
- " branch %i=> HALT\n", current->id, i);
+ PRINT(0,"domain %i.%i is blocked but still on L1 xq"\
+ " branch %i=> HALT\n", current->domain->id,
+ current->eid, i);
sedf_dump_cpu_state(0);(*((int*)0))++;
}
if (__task_on_queue(current)) {
- PRINT(0,"domain %i is blocked but still on run/waitq"\
- " branch %i=> HALT\n",current->id,i);
+ PRINT(0,"domain %i.%i is blocked but still on run/waitq"\
+ " branch %i=> HALT\n",current->domain->id,
+ d->eid,i);
sedf_dump_cpu_state(0);(*((int*)0))++;
}
}*/
check_waitq:
update_queues(now, runq, waitq);
- /*now simply pick the first domain from the runqueue*/
- struct sedf_dom_info *runinf, *waitinf;
+ /*now simply pick the first domain from the runqueue, which has the
+ earliest deadline, because the list is sorted*/
+ struct sedf_edom_info *runinf, *waitinf;
if (!list_empty(runq)) {
- runinf = list_entry(runq->next,struct sedf_dom_info,list);
- ret.task = runinf->owner;
+ runinf = list_entry(runq->next,struct sedf_edom_info,list);
+ ret.task = runinf->exec_domain;
if (!list_empty(waitq)) {
waitinf = list_entry(waitq->next,
- struct sedf_dom_info,list);
+ struct sedf_edom_info,list);
/*rerun scheduler, when scheduled domain reaches it's
end of slice or the first domain from the waitqueue
gets ready*/
else {
ret.time = runinf->slice - runinf->cputime;
}
+ ASSERT(ret.time > now);
goto sched_done;
}
if (!list_empty(waitq)) {
- waitinf = list_entry(waitq->next,struct sedf_dom_info,list);
+ waitinf = list_entry(waitq->next,struct sedf_edom_info, list);
/*we could not find any suitable domain
=> look for domains that are aware of extratime*/
#if (EXTRA > EXTRA_OFF)
ret.task = IDLETASK(cpu);
ret.time = PERIOD_BEGIN(waitinf) - now;
#endif
+ ASSERT(ret.time > now);
}
else {
/*this could probably never happen, but one never knows...*/
ret.time);
ret.time = EXTRA_QUANTUM;
}
- DOM_INFO(ret.task)->sched_start=now;
+ EDOM_INFO(ret.task)->sched_start_abs = now;
return ret;
}
-static void sedf_sleep(struct domain *d) {
- PRINT(2,"sedf_sleep was called, domain-id %i\n",d->id);
- if ( test_bit(DF_RUNNING, &d->flags) ) {
+static void sedf_sleep(struct exec_domain *d) {
+ PRINT(2,"sedf_sleep was called, domain-id %i.%i\n",d->domain->id, d->eid);
+ if ( test_bit(EDF_RUNNING, &d->ed_flags) ) {
#ifdef ADV_SCHED_HISTO
adv_sched_hist_start(d->processor);
#endif
* opposed to approaches 1,2a,2b
*/
static inline void unblock_short_vcons
-(struct sedf_dom_info* inf, s_time_t now) {
- inf->absdead += inf->period;
+(struct sedf_edom_info* inf, s_time_t now) {
+ inf->deadl_abs += inf->period;
inf->cputime = 0;
}
-static inline void unblock_short_cons(struct sedf_dom_info* inf, s_time_t now)
+static inline void unblock_short_cons(struct sedf_edom_info* inf, s_time_t now)
{
/*treat blocked time as consumed by the domain*/
- inf->cputime += now - inf->absblock;
+ inf->cputime += now - inf->block_abs;
if (inf->cputime + EXTRA_QUANTUM > inf->slice) {
/*we don't have a reasonable amount of time in
our slice left :( => start in next period!*/
inf->short_cont++;
#endif
}
-static inline void unblock_short_extra_support (struct sedf_dom_info* inf,
+static inline void unblock_short_extra_support (struct sedf_edom_info* inf,
s_time_t now) {
/*this unblocking scheme tries to support the domain, by assigning it
a priority in extratime distribution according to the loss of time
s_time_t pen;
/*no more realtime execution in this period!*/
- inf->absdead += inf->period;
- if (likely(inf->absblock)) {
+ inf->deadl_abs += inf->period;
+ if (likely(inf->block_abs)) {
//treat blocked time as consumed by the domain*/
- /*inf->cputime += now - inf->absblock;*/
+ /*inf->cputime += now - inf->block_abs;*/
+ /*penalty is time the domain would have
+ had if it continued to run */
pen = (inf->slice - inf->cputime);
if (pen < 0) pen = 0;
/*accumulate all penalties over the periods*/
#ifdef SEDF_STATS
inf->pen_extra_blocks++;
#endif
- if (extraq_on(inf->owner, EXTRA_PEN_Q))
+ if (extraq_on(inf->exec_domain, EXTRA_PEN_Q))
/*remove domain for possible resorting!*/
- extraq_del(inf->owner, EXTRA_PEN_Q);
+ extraq_del(inf->exec_domain, EXTRA_PEN_Q);
else
/*remember that we want to be on the penalty q
so that we can continue when we (un-)block
inf->extra |= EXTRA_WANT_PEN_Q;
/*(re-)add domain to the penalty extraq*/
- extraq_add_sort_update(inf->owner,
+ extraq_add_sort_update(inf->exec_domain,
EXTRA_PEN_Q, 0);
}
}
/*give it a fresh slice in the next period!*/
inf->cputime = 0;
}
-static inline void unblock_long_vcons(struct sedf_dom_info* inf, s_time_t now)
+static inline void unblock_long_vcons(struct sedf_edom_info* inf, s_time_t now)
{
/* align to next future period */
- inf->absdead += ((now - inf->absdead) / inf->period + 1)
+ inf->deadl_abs += (DIV_UP(now - inf->deadl_abs, inf->period) +1)
* inf->period;
inf->cputime = 0;
}
-static inline void unblock_long_cons_a (struct sedf_dom_info* inf,
+static inline void unblock_long_cons_a (struct sedf_edom_info* inf,
s_time_t now) {
/*treat the time the domain was blocked in the
CURRENT period as consumed by the domain*/
- inf->cputime = (now - inf->absdead) % inf->period;
+ inf->cputime = (now - inf->deadl_abs) % inf->period;
if (inf->cputime + EXTRA_QUANTUM > inf->slice) {
/*we don't have a reasonable amount of time in our slice
left :( => start in next period!*/
unblock_long_vcons(inf, now);
}
}
-static inline void unblock_long_cons_b(struct sedf_dom_info* inf,s_time_t now) {
+static inline void unblock_long_cons_b(struct sedf_edom_info* inf,s_time_t now) {
/*Conservative 2b*/
/*Treat the unblocking time as a start of a new period */
- inf->absdead = now + inf->period;
+ inf->deadl_abs = now + inf->period;
inf->cputime = 0;
}
-static inline void unblock_long_cons_c(struct sedf_dom_info* inf,s_time_t now) {
+static inline void unblock_long_cons_c(struct sedf_edom_info* inf,s_time_t now) {
if (likely(inf->latency)) {
/*scale the slice and period accordingly to the latency hint*/
/*reduce period temporarily to the latency hint*/
/*scale slice accordingly, so that utilisation stays the same*/
inf->slice = (inf->period * inf->slice_orig)
/ inf->period_orig;
- inf->absdead = now + inf->period;
+ inf->deadl_abs = now + inf->period;
inf->cputime = 0;
}
else {
}
}
/*a new idea of dealing with short blocks: burst period scaling*/
-static inline void unblock_short_burst(struct sedf_dom_info* inf, s_time_t now)
+static inline void unblock_short_burst(struct sedf_edom_info* inf, s_time_t now)
{
/*treat blocked time as consumed by the domain*/
- inf->cputime += now - inf->absblock;
+ inf->cputime += now - inf->block_abs;
if (inf->cputime + EXTRA_QUANTUM <= inf->slice) {
/*if we can still use some time in the current slice
else {
/*we don't have a reasonable amount of time in
our slice left => switch to burst mode*/
- if (likely(inf->absunblock)) {
+ if (likely(inf->unblock_abs)) {
/*set the period-length to the current blocking
interval, possible enhancements: average over last
blocking intervals, user-specified minimum,...*/
- inf->period = now - inf->absunblock;
+ inf->period = now - inf->unblock_abs;
/*check for overflow on multiplication*/
ASSERT((inf->period < ULONG_MAX)
&& (inf->slice_orig < ULONG_MAX));
inf->slice = (inf->period * inf->slice_orig)
/ inf->period_orig;
/*set new (shorter) deadline*/
- inf->absdead += inf->period;
+ inf->deadl_abs += inf->period;
}
else {
/*in case we haven't unblocked before
start in next period!*/
inf->cputime=0;
- inf->absdead += inf->period;
+ inf->deadl_abs += inf->period;
}
}
- inf->absunblock = now;
+ inf->unblock_abs = now;
}
-static inline void unblock_long_burst(struct sedf_dom_info* inf,s_time_t now) {
+static inline void unblock_long_burst(struct sedf_edom_info* inf, s_time_t now) {
if (unlikely(inf->latency && (inf->period > inf->latency))) {
/*scale the slice and period accordingly to the latency hint*/
inf->period = inf->latency;
/*scale slice accordingly, so that utilisation stays the same*/
inf->slice = (inf->period * inf->slice_orig)
/ inf->period_orig;
- inf->absdead = now + inf->period;
+ inf->deadl_abs = now + inf->period;
inf->cputime = 0;
}
else {
when we are in sync with the device!*/
unblock_long_cons_b(inf, now);
}
- inf->absunblock = now;
+ inf->unblock_abs = now;
}
#define DOMAIN_EDF 1
#define DOMAIN_EXTRA_PEN 2
#define DOMAIN_EXTRA_UTIL 3
#define DOMAIN_IDLE 4
-static inline int get_run_type(struct domain* d) {
- struct sedf_dom_info* inf = DOM_INFO(d);
- if (is_idle_task(d))
+static inline int get_run_type(struct exec_domain* d) {
+ struct sedf_edom_info* inf = EDOM_INFO(d);
+ if (is_idle_task(d->domain))
return DOMAIN_IDLE;
if (inf->extra & EXTRA_RUN_PEN)
return DOMAIN_EXTRA_PEN;
In the same class priorities are assigned as following:
EDF: early deadline > late deadline
L0 extra-time: lower score > higher score*/
-static inline int should_switch(struct domain* cur, struct domain* other,
- s_time_t now) {
- struct sedf_dom_info *cur_inf, *other_inf;
- cur_inf = DOM_INFO(cur);
- other_inf = DOM_INFO(other);
+static inline int should_switch(struct exec_domain* cur,
+ struct exec_domain* other, s_time_t now) {
+ struct sedf_edom_info *cur_inf, *other_inf;
+ cur_inf = EDOM_INFO(cur);
+ other_inf = EDOM_INFO(other);
/*check whether we need to make an earlier sched-decision*/
if ((PERIOD_BEGIN(other_inf) <
return 1;
}
}
-void sedf_wake(struct domain *d) {
+void sedf_wake(struct exec_domain *d) {
s_time_t now = NOW();
- struct sedf_dom_info* inf = DOM_INFO(d);
+ struct sedf_edom_info* inf = EDOM_INFO(d);
- PRINT(3,"sedf_wake was called, domain-id %i\n",d->id);
+ PRINT(3,"sedf_wake was called, domain-id %i.%i\n",d->domain->id, d->eid);
- if (unlikely(is_idle_task(d)))
+ if (unlikely(is_idle_task(d->domain)))
return;
if ( unlikely(__task_on_queue(d)) ) {
- PRINT(3,"\tdomain %i is already in some queue\n",d->id);
+ PRINT(3,"\tdomain %i.%i is already in some queue\n",
+ d->domain->id, d->eid);
return;
}
if ( unlikely(extraq_on(d,EXTRA_UTIL_Q) || extraq_on(d,EXTRA_PEN_Q)) ) {
- PRINT(3,"\tdomain %i is already in the extraQ\n",d->id);
+ PRINT(3,"\tdomain %i.%i is already in the extraQ\n",
+ d->domain->id, d->eid);
}
- if (unlikely(inf->absdead == 0))
+ if (unlikely(inf->deadl_abs == 0))
/*initial setup of the deadline*/
- inf->absdead = now + inf->slice;
+ inf->deadl_abs = now + inf->slice;
- PRINT(3,"waking up domain %i (deadl= %llu period= %llu "\
- "now= %llu)\n",d->id,inf->absdead,inf->period,now);
+ PRINT(3,"waking up domain %i.%i (deadl= %llu period= %llu "\
+ "now= %llu)\n", d->domain->id, d->eid, inf->deadl_abs,
+ inf->period, now);
#ifdef SEDF_STATS
inf->block_tot++;
#endif
- if (unlikely(now< PERIOD_BEGIN(inf))) {
+ if (unlikely(now < PERIOD_BEGIN(inf))) {
PRINT(4,"extratime unblock\n");
/*this might happen, imagine unblocking in extra-time!*/
#if (EXTRA == EXTRA_BLOCK_WEIGHT)
/*This is very very unlikely, ie. might even be an error?!*/
}
else {
- if (now < inf->absdead) {
+ if (now < inf->deadl_abs) {
PRINT(4,"short unblocking\n");
/*short blocking*/
#ifdef SEDF_STATS
}
}
- PRINT(3,"woke up domain %i (deadl= %llu period= %llu "\
- "now= %llu)\n",d->id,inf->absdead,inf->period,now);
+ PRINT(3,"woke up domain %i.%i (deadl= %llu period= %llu "\
+ "now= %llu)\n", d->domain->id, d->eid, inf->deadl_abs,
+ inf->period, now);
__add_to_waitqueue_sort(d);
PRINT(3,"added to waitq\n");
#ifdef SEDF_STATS
/*do some statistics here...*/
- if (inf->absblock != 0) {
- inf->block_time_tot += now - inf->absblock;
+ if (inf->block_abs != 0) {
+ inf->block_time_tot += now - inf->block_abs;
inf->penalty_time_tot +=
- PERIOD_BEGIN(inf) + inf->cputime - inf->absblock;
+ PERIOD_BEGIN(inf) + inf->cputime - inf->block_abs;
}
#endif
/*sanity check: make sure each extra-aware domain IS on the util-q!*/
/*if (inf->extra & EXTRA_AWARE) {
if (!extraq_on(d, EXTRA_UTIL_Q))
- printf("sedf_wake: domain %i is extra-aware, "\
- "but NOT on L1 extraq!\n",d->id);
+ printf("sedf_wake: domain %i.%i is extra-aware, "\
+ "but NOT on L1 extraq!\n",d->domain->id, d->eid);
}*/
/*check whether the awakened task needs to invoke the do_schedule
}
/*Print a lot of use-{full, less} information about a domains in the system*/
-static void sedf_dump_domain(struct domain *d) {
- printk("%u has=%c ", d->id,
- test_bit(DF_RUNNING, &d->flags) ? 'T':'F');
+static void sedf_dump_domain(struct exec_domain *d) {
+ printk("%i.%i has=%c ", d->domain->id, d->eid,
+ test_bit(EDF_RUNNING, &d->ed_flags) ? 'T':'F');
printk("p=%llu sl=%llu ddl=%llu w=%hu c=%llu sc=%i xtr(%s)=%llu",
- DOM_INFO(d)->period, DOM_INFO(d)->slice, DOM_INFO(d)->absdead,
- DOM_INFO(d)->weight, d->cpu_time, DOM_INFO(d)->score[EXTRA_UTIL_Q],
- (DOM_INFO(d)->extra & EXTRA_AWARE) ? "yes" : "no",
- DOM_INFO(d)->extra_time_tot);
+ EDOM_INFO(d)->period, EDOM_INFO(d)->slice, EDOM_INFO(d)->deadl_abs,
+ EDOM_INFO(d)->weight, d->cpu_time, EDOM_INFO(d)->score[EXTRA_UTIL_Q],
+ (EDOM_INFO(d)->extra & EXTRA_AWARE) ? "yes" : "no",
+ EDOM_INFO(d)->extra_time_tot);
if (d->cpu_time !=0)
- printf(" (%lu%)", (DOM_INFO(d)->extra_time_tot * 100)
+ printf(" (%lu%)", (EDOM_INFO(d)->extra_time_tot * 100)
/ d->cpu_time);
#ifdef SEDF_STATS
- if (DOM_INFO(d)->block_time_tot!=0)
- printf(" pen=%lu%", (DOM_INFO(d)->penalty_time_tot * 100) /
- DOM_INFO(d)->block_time_tot);
- if (DOM_INFO(d)->block_tot!=0)
+ if (EDOM_INFO(d)->block_time_tot!=0)
+ printf(" pen=%lu%", (EDOM_INFO(d)->penalty_time_tot * 100) /
+ EDOM_INFO(d)->block_time_tot);
+ if (EDOM_INFO(d)->block_tot!=0)
printf("\n blks=%lu sh=%lu (%lu%) (shc=%lu (%lu%) shex=%i "\
"shexsl=%i) l=%lu (%lu%) avg: b=%llu p=%llu",
- DOM_INFO(d)->block_tot, DOM_INFO(d)->short_block_tot,
- (DOM_INFO(d)->short_block_tot * 100)
- / DOM_INFO(d)->block_tot, DOM_INFO(d)->short_cont,
- (DOM_INFO(d)->short_cont * 100) / DOM_INFO(d)->block_tot,
- DOM_INFO(d)->pen_extra_blocks,
- DOM_INFO(d)->pen_extra_slices,
- DOM_INFO(d)->long_block_tot,
- (DOM_INFO(d)->long_block_tot * 100) / DOM_INFO(d)->block_tot,
- (DOM_INFO(d)->block_time_tot) / DOM_INFO(d)->block_tot,
- (DOM_INFO(d)->penalty_time_tot) / DOM_INFO(d)->block_tot);
+ EDOM_INFO(d)->block_tot, EDOM_INFO(d)->short_block_tot,
+ (EDOM_INFO(d)->short_block_tot * 100)
+ / EDOM_INFO(d)->block_tot, EDOM_INFO(d)->short_cont,
+ (EDOM_INFO(d)->short_cont * 100) / EDOM_INFO(d)->block_tot,
+ EDOM_INFO(d)->pen_extra_blocks,
+ EDOM_INFO(d)->pen_extra_slices,
+ EDOM_INFO(d)->long_block_tot,
+ (EDOM_INFO(d)->long_block_tot * 100) / EDOM_INFO(d)->block_tot,
+ (EDOM_INFO(d)->block_time_tot) / EDOM_INFO(d)->block_tot,
+ (EDOM_INFO(d)->penalty_time_tot) / EDOM_INFO(d)->block_tot);
#endif
printf("\n");
}
/*dumps all domains on hte specified cpu*/
static void sedf_dump_cpu_state(int i)
{
- struct list_head *list, *queue, *tmp;
+ struct list_head *list, *queue, *tmp;
+ struct sedf_edom_info *d_inf;
+ struct domain *d;
+ struct exec_domain *ed;
int loop = 0;
- struct sedf_dom_info *d_inf;
- struct domain* d;
printk("now=%llu\n",NOW());
queue = RUNQ(i);
(unsigned long) queue->next, (unsigned long) queue->prev);
list_for_each_safe ( list, tmp, queue ) {
printk("%3d: ",loop++);
- d_inf = list_entry(list, struct sedf_dom_info, list);
- sedf_dump_domain(d_inf->owner);
+ d_inf = list_entry(list, struct sedf_edom_info, list);
+ sedf_dump_domain(d_inf->exec_domain);
}
queue = WAITQ(i); loop = 0;
(unsigned long) queue->next, (unsigned long) queue->prev);
list_for_each_safe ( list, tmp, queue ) {
printk("%3d: ",loop++);
- d_inf = list_entry(list, struct sedf_dom_info, list);
- sedf_dump_domain(d_inf->owner);
+ d_inf = list_entry(list, struct sedf_edom_info, list);
+ sedf_dump_domain(d_inf->exec_domain);
}
queue = EXTRAQ(i,EXTRA_PEN_Q); loop = 0;
(unsigned long)queue, (unsigned long) queue->next,
(unsigned long) queue->prev);
list_for_each_safe ( list, tmp, queue ) {
- d_inf = list_entry(list, struct sedf_dom_info,
+ d_inf = list_entry(list, struct sedf_edom_info,
extralist[EXTRA_PEN_Q]);
printk("%3d: ",loop++);
- sedf_dump_domain(d_inf->owner);
+ sedf_dump_domain(d_inf->exec_domain);
}
queue = EXTRAQ(i,EXTRA_UTIL_Q); loop = 0;
(unsigned long)queue, (unsigned long) queue->next,
(unsigned long) queue->prev);
list_for_each_safe ( list, tmp, queue ) {
- d_inf = list_entry(list, struct sedf_dom_info,
+ d_inf = list_entry(list, struct sedf_edom_info,
extralist[EXTRA_UTIL_Q]);
printk("%3d: ",loop++);
- sedf_dump_domain(d_inf->owner);
+ sedf_dump_domain(d_inf->exec_domain);
}
loop = 0;
printk("\nnot on Q\n");
- for_each_domain(d) {
- if (!__task_on_queue(d) && (d->processor == i)) {
- printk("%3d: ",loop++);
- sedf_dump_domain(d);
+ for_each_domain(d)
+ for_each_exec_domain(d, ed)
+ {
+ if (!__task_on_queue(ed) && (ed->processor == i)) {
+ printk("%3d: ",loop++);
+ sedf_dump_domain(ed);
+ }
}
- }
}
/*Adjusts periods and slices of the domains accordingly to their weights*/
-static inline int sedf_adjust_weights(struct domain *p,
-struct sched_adjdom_cmd *cmd) {
- int sumw[NR_CPUS];
- s_time_t sumt[NR_CPUS];
- int cpu;
+static inline int sedf_adjust_weights(struct sched_adjdom_cmd *cmd) {
+ struct exec_domain *p;
+ struct domain *d;
+ int sumw[NR_CPUS];
+ s_time_t sumt[NR_CPUS];
+ int cpu;
for (cpu=0; cpu < NR_CPUS; cpu++) {
sumw[cpu] = 0;
sumt[cpu] = 0;
}
/*sum up all weights*/
- for_each_domain(p) {
- if (DOM_INFO(p)->weight)
- sumw[p->processor] += DOM_INFO(p)->weight;
+ for_each_domain(d)
+ for_each_exec_domain(d, p) {
+ if (EDOM_INFO(p)->weight)
+ sumw[p->processor] += EDOM_INFO(p)->weight;
else {
/*don't modify domains who don't have a weight, but sum
up the time they need, projected to a WEIGHT_PERIOD,
domains*/
/*check for overflows*/
ASSERT((WEIGHT_PERIOD < ULONG_MAX)
- && (DOM_INFO(p)->slice_orig < ULONG_MAX));
+ && (EDOM_INFO(p)->slice_orig < ULONG_MAX));
sumt[p->processor] += (WEIGHT_PERIOD *
- DOM_INFO(p)->slice_orig) / DOM_INFO(p)->period_orig;
+ EDOM_INFO(p)->slice_orig) / EDOM_INFO(p)->period_orig;
}
}
/*adjust all slices (and periods) to the new weight*/
- for_each_domain(p) {
- if (DOM_INFO(p)->weight) {
- DOM_INFO(p)->period_orig =
- DOM_INFO(p)->period = WEIGHT_PERIOD;
- DOM_INFO(p)->slice_orig =
- DOM_INFO(p)->slice = (DOM_INFO(p)->weight *
+ for_each_domain(d)
+ for_each_exec_domain(d, p) {
+ if (EDOM_INFO(p)->weight) {
+ EDOM_INFO(p)->period_orig =
+ EDOM_INFO(p)->period = WEIGHT_PERIOD;
+ EDOM_INFO(p)->slice_orig =
+ EDOM_INFO(p)->slice = (EDOM_INFO(p)->weight *
(WEIGHT_PERIOD -WEIGHT_SAFETY -
sumt[p->processor])) / sumw[p->processor];
}
/* set or fetch domain scheduling parameters */
static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) {
+ struct exec_domain *ed;
+
PRINT(2,"sedf_adjdom was called, domain-id %i new period %llu "\
"new slice %llu\nlatency %llu extra:%s\n",
p->id, cmd->u.sedf.period, cmd->u.sedf.slice,
return -EINVAL;
/*weight driven domains*/
if (cmd->u.sedf.weight) {
- DOM_INFO(p)->weight = cmd->u.sedf.weight;
+ for_each_exec_domain(p, ed)
+ EDOM_INFO(ed)->weight = cmd->u.sedf.weight;
}
else {
/*time driven domains*/
- DOM_INFO(p)->weight = 0;
- /* sanity checking! */
- if(cmd->u.sedf.slice > cmd->u.sedf.period )
- return -EINVAL;
- DOM_INFO(p)->period_orig =
- DOM_INFO(p)->period = cmd->u.sedf.period;
- DOM_INFO(p)->slice_orig =
- DOM_INFO(p)->slice = cmd->u.sedf.slice;
+ for_each_exec_domain(p, ed) {
+ /* sanity checking! */
+ if(cmd->u.sedf.slice > cmd->u.sedf.period )
+ return -EINVAL;
+ EDOM_INFO(ed)->weight = 0;
+ EDOM_INFO(ed)->period_orig =
+ EDOM_INFO(ed)->period = cmd->u.sedf.period;
+ EDOM_INFO(ed)->slice_orig =
+ EDOM_INFO(ed)->slice = cmd->u.sedf.slice;
+ }
}
- if (sedf_adjust_weights(p,cmd))
+ if (sedf_adjust_weights(cmd))
return -EINVAL;
- DOM_INFO(p)->extra = (DOM_INFO(p)-> extra & ~EXTRA_AWARE)
- | (cmd->u.sedf.extratime & EXTRA_AWARE);
- DOM_INFO(p)->latency = cmd->u.sedf.latency;
- extraq_check(p);
+
+ for_each_exec_domain(p, ed) {
+ EDOM_INFO(ed)->extra = (EDOM_INFO(ed)->extra &
+ ~EXTRA_AWARE) | (cmd->u.sedf.extratime & EXTRA_AWARE);
+ EDOM_INFO(ed)->latency = cmd->u.sedf.latency;
+ extraq_check(ed);
+ }
}
else if ( cmd->direction == SCHED_INFO_GET )
{
- cmd->u.sedf.period = DOM_INFO(p)->period;
- cmd->u.sedf.slice = DOM_INFO(p)->slice;
- cmd->u.sedf.extratime = DOM_INFO(p)->extra & EXTRA_AWARE;
- cmd->u.sedf.latency = DOM_INFO(p)->latency;
- cmd->u.sedf.weight = DOM_INFO(p)->weight;
+ cmd->u.sedf.period = EDOM_INFO(p->exec_domain[0])->period;
+ cmd->u.sedf.slice = EDOM_INFO(p->exec_domain[0])->slice;
+ cmd->u.sedf.extratime = EDOM_INFO(p->exec_domain[0])->extra
+ & EXTRA_AWARE;
+ cmd->u.sedf.latency = EDOM_INFO(p->exec_domain[0])->latency;
+ cmd->u.sedf.weight = EDOM_INFO(p->exec_domain[0])->weight;
}
PRINT(2,"sedf_adjdom_finished\n");
return 0;